<?php

namespace App\Kuafu\ProductMenu\Service;

use App\Exceptions\CustomValidateException;
use App\Kuafu\Audit\Enum\AuditEventCodeEnum;
use App\Kuafu\Audit\Service\AuditService;
use App\Kuafu\Base\Service\BaseService;
use App\Kuafu\Category\Model\CategoryModel;
use App\Kuafu\Mqtt\Service\MqttQueueService;
use App\Kuafu\Mqtt\Service\MqttService;
use App\Kuafu\Product\Enum\CodeEnum;
use App\Kuafu\Product\Enum\ProductCacheEnum;
use App\Kuafu\Product\Model\PackageProductMapping;
use App\Kuafu\Product\Model\Product;
use App\Kuafu\ProductMenu\Enum\ProductMenuCodeEnum;
use App\Kuafu\ProductMenu\Exceptions\ProductMenuException;
use App\Kuafu\ProductMenu\Model\ProductMenu;
use App\Kuafu\ProductMenu\Validate\ProductMenuV2Validate;
use App\Kuafu\Shop\Enum\ShopCacheEnum;
use App\Kuafu\Shop\Model\Shop;
use App\Kuafu\Shop\Model\ShopProductStatus;
use App\Kuafu\User\Exceptions\UserException;
use App\Kuafu\User\Service\AuthService;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;

class ProductMenuBatchService extends BaseService
{
    public function __construct($brandId = 0, $shopId = 0) { parent::__construct($brandId, $shopId); }

    /**
     * @param string $shopIds
     * @param string $productIds
     * @param int $handleType
     * @return void|null
     * @throws ProductMenuException
     * @throws UserException
     * @throws CustomValidateException
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function batchSend(string $shopIds, string $productIds, int $handleType)
    {
        // 1 添加
        if ($handleType == 1) {
            $params = (array)ProductMenuV2Validate::batchAddValidate(request()->all());
            $this->batchAdd($shopIds, $productIds, $params["fields"]);
        } else {
            $this->batchDelete($shopIds, $productIds);
        }
    }

    /**
     * @param string $shopIds
     * @param string $productIds
     * @param array $fields
     * @return void
     * @throws ProductMenuException
     * @throws UserException
     */
    private function batchAdd(string $shopIds, string $productIds, array $fields)
    {
        $shopIds    = array_filter(explode(',', $shopIds));
        $productIds = array_filter(explode(',', $productIds));

        if (empty($shopIds) || empty($productIds)) {
            throw new ProductMenuException(ProductMenuCodeEnum::ERR_FOOD_MENUS_PARAM);
        }

        $shopList = Shop::query()->whereIn('id', $shopIds)->get();

        $menusIds = $shopList->pluck('menuId')->unique()->filter()->values();

        $menusList = ProductMenu::query()
                                ->whereIn('id', $menusIds)
                                ->get();


        $productOrgList = Product::query()->whereIn('id', $productIds)->where('menuId', 0)->get()->toArray();

        foreach ($menusList as $menusInfo) {
            DB::beginTransaction();
            try {
                foreach ($productOrgList as $productOrgInfo) {
                    $productInfo = $productOrgInfo;

                    Product::query()
                           ->where('id', $productOrgInfo['id'])
                           ->where('menuId', $menusInfo['id'])
                           ->where("isDeleted", 1)
                           ->withoutGlobalScope('isDel')
                           ->delete();

                    $categoryInfo = Cache::remember('CategoryModelTmp' . $productOrgInfo['categoryId'] . ':' . $menusInfo['id'],
                        60, function () use ($productOrgInfo, $menusInfo) {
                            return CategoryModel::query()->where('pid', $productOrgInfo['categoryId'])
                                                ->where('menuId', $menusInfo['id'])->first();
                        });

                    if (empty($categoryInfo)) {
                        throw new ProductMenuException(ProductMenuCodeEnum::ERR_FOOD_MENUS_PARAM,
                            vsprintf('菜单[%s]中不存在分类 ID[%s]的分类, 请检查后再试', [
                                $menusInfo['name'],
                                $productOrgInfo['categoryId']
                            ]));
                    }

                    $productInfo['categoryId'] = $categoryInfo['id'];
                    $productInfo['menuId']     = $menusInfo['id'];

                    Product::fieldsUpdateOrCreate(
                        [
                            "id"     => $productOrgInfo['id'],
                            "menuId" => $menusInfo['id']
                        ],
                        $productInfo,
                        $fields
                    );


                    // todo 门店菜单定制表 重置门店渠道展示
//                    if (in_array("showPlatform", $fields)) {
//                        ShopProductStatus::query()
//                                         ->where("productId", $productOrgInfo['id'])
//                                         ->whereIn("shopId", $shopIds)
//                                         ->update([
//                                             "showPlatform" => 1,
//                                             "updatedAt"    => time()
//                                         ]);
//                    }



//                    Product::query()->create($productInfo);
                    // 如果是套餐还需要添加子菜
                    if ($productOrgInfo['type'] == CodeEnum::PRODUCT_TYPE_PACKAGE) {
                        //  获取子菜
                        $productOrgSon = PackageProductMapping::query()->where('packageId', $productOrgInfo['id'])
                                                              ->where('menuId', 0)
                                                              ->get()->toArray();

                        PackageProductMapping::query()
                                             ->where('packageId', $productOrgInfo['id'])
                                             ->where('menuId', $menusInfo->id)
                                             ->withoutGlobalScope('isDel')
                                             ->delete();

                        $productSon = $productOrgSon;

                        foreach ($productSon as $key => &$value) {
                            unset($productSon[$key]['id']);
                            $value['menuId'] = $menusInfo->id;
                        }
                        $insertData = $productSon;
                        PackageProductMapping::query()->insert($insertData);
                    }
                }
                Cache::forget(ProductCacheEnum::getProductList($menusInfo['id']));
                DB::commit();
            } catch (\Exception $exception) {
                DB::rollBack();
                throw new ProductMenuException(ProductMenuCodeEnum::ERR_FOOD_MENUS_BATCH_ERROR,
                    $exception->getMessage(), $exception);
            }
        }

//        // 下发更新菜单MQTT
//        foreach ($shopIds as $shopId) {
//            (new MqttService(0, $shopId))->updateProductMenu();
//        }
        MqttQueueService::updateProductMenu($shopIds);

        // 审计机器人
        $user    = AuthService::getAuthUser();
        $content = "触发人名: " . $user['username'] . PHP_EOL;
        $content .= '下发-新增-菜品: ';
        unset($value);
        foreach ($productOrgList as $value) {
            $content .= $value['name'] . ',';
        }
        $content .= PHP_EOL;
        $content .= PHP_EOL . '下发门店: ' . PHP_EOL;
        foreach ($shopList as $value) {
            $content .= $value['name'] . PHP_EOL;
        }

        $content .= PHP_EOL . '下发菜单: ' . PHP_EOL;
        foreach ($menusList as $value) {
            $content .= $value['name'] . PHP_EOL;
        }

        $content .= PHP_EOL . '下发菜品id: ' . PHP_EOL;
        foreach ($productOrgList as $value) {
            $content .= $value["id"] . "-" . $value['name'] . PHP_EOL;
        }

        $content .= PHP_EOL . '下发菜品字段信息: ' . PHP_EOL;
        $content .= collect(Product::FIELDS_TEXT)->only($fields)->values()->implode(",") . PHP_EOL;

        AuditService::sendNotify(AuditEventCodeEnum::EVENT_TYPE_10004, $content);
    }

    /**
     * @throws ProductMenuException
     */
    private function batchDelete(string $shopIds, string $productIds)
    {
        $shopIds    = array_filter(explode(',', $shopIds));
        $productIds = array_filter(explode(',', $productIds));

        if (empty($shopIds) || empty($productIds)) {
            throw new ProductMenuException(ProductMenuCodeEnum::ERR_FOOD_MENUS_PARAM);
        }

        $shopList = Shop::query()->whereIn('id', $shopIds)->get();

        $menusIds = $shopList->pluck('menuId')->unique()->filter()->values();

        $menusList = ProductMenu::query()
                                ->whereIn('id', $menusIds)
                                ->get();

        $productOrgList = Product::query()->whereIn('id', $productIds)->where('menuId', 0)->get()->toArray();

        // 判断商品是否是套餐, 非套餐这个渠道不能操作
//        foreach ($productOrgList as $value) {
//            if ($value['type'] != CodeEnum::PRODUCT_TYPE_PACKAGE) {
//                throw new ProductMenuException(ProductMenuCodeEnum::ERR_FOOD_MENUS_PARAM,
//                    vsprintf('商品[%s]不是套餐, 不能通过这个渠道操作', [
//                        $value['name']
//                    ]));
//            }
//        }

        foreach ($menusList as $menusInfo) {
            DB::beginTransaction();
            try {
                foreach ($productOrgList as $productOrgInfo) {

                    Product::query()
                           ->where('id', $productOrgInfo['id'])
                           ->where('menuId', $menusInfo['id'])
                           ->withoutGlobalScope('isDel')
                           ->delete();

                    ShopProductStatus::query()->where('productId', $productOrgInfo['id'])
                                     ->whereIn('shopId', $shopIds)
                                     ->delete();

                    // 如果是套餐还需要删除子菜
                    if ($productOrgInfo['type'] == CodeEnum::PRODUCT_TYPE_PACKAGE) {
                        //  获取子菜
                        PackageProductMapping::query()
                                             ->where('packageId', $productOrgInfo['id'])
                                             ->where('menuId', $menusInfo->id)
                                             ->withoutGlobalScope('isDel')
                                             ->delete();
                    }
                }
                Cache::forget(ProductCacheEnum::getProductList($menusInfo['id']));
                DB::commit();
            } catch (\Exception $exception) {
                DB::rollBack();
                throw new ProductMenuException(ProductMenuCodeEnum::ERR_FOOD_MENUS_BATCH_ERROR,
                    $exception->getMessage(), $exception);
            }
        }

        MqttQueueService::updateProductMenu($shopIds);

        // 审计机器人
        $user    = AuthService::getAuthUser();
        $content = "触发人名: " . $user['username'] . PHP_EOL;
        $content .= '下发-删除-菜品: ';
        unset($value);
        foreach ($productOrgList as $value) {
            $content .= $value['name'] . ',';
        }
        $content .= PHP_EOL;
        $content .= PHP_EOL . '下发门店: ' . PHP_EOL;
        foreach ($shopList as $value) {
            $content .= $value['name'] . PHP_EOL;
        }
        AuditService::sendNotify(AuditEventCodeEnum::EVENT_TYPE_10004, $content);
    }

}
